package esdclibrarysystem;

import com.esdc.librarysystem.datastate.BookLoanState;
import com.esdc.librarysystem.datastate.BookState;
import com.esdc.librarysystem.datastate.ReservationState;
import com.esdc.librarysystem.exception.ExistException;
import com.esdc.librarysystem.exception.HasOutstandingLoan;
import com.esdc.librarysystem.exception.LibraryPolicyException;
import com.esdc.librarysystem.exception.LoanLimitException;
import com.esdc.librarysystem.exception.NotExistException;
import com.esdc.librarysystem.manager.CollectionManagerRemote;
import com.esdc.librarysystem.manager.LoanManagerRemote;
import com.esdc.librarysystem.manager.MemberManagerRemote;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author shou1dwe
 */
public class Control {

    private CollectionManagerRemote collectionManager;
    private LoanManagerRemote loanManager;
    private MemberManagerRemote memberManager;
    private Input input = new Input();

    public Control() {
        collectionManager = Main.collectionManager;
        loanManager = Main.loanManager;
        memberManager = Main.memberManager;
    }

    public void registerAccount() {
        String name, type, password;
        String department, faculty, telNumber, email;
        long id = -1;
        if (Main.isDebug) {
            id = memberManager.addMember("name", "type", "ppswd", "dep", "ema", "fa", "000");
        } else {
            name = input.getString("name");
            type = input.getString("type(student or staff)");
            while(!type.toLowerCase().equals("student") && !type.toLowerCase().equals("staff")){
                print("Wrong input format: ONLY 'student' or 'staff' allowed");
                type = input.getString("type(student or staff)");
            }
            password = input.getString("password");
            department = input.getString("department");
            faculty = input.getString("faculty");
            telNumber = input.getString("telephone number");
            email = input.getString("email");
            id = memberManager.addMember(name, type, password, department, email, faculty, telNumber);
        }

        print(String.format("New member added. (ID: %d)", id));
    }

    public void terminateMembership() {
        try {
            if (Main.isDebug) {
                memberManager.deleteMember(1);
            } else {
                String name = input.getString("name");
                List<Object> members = memberManager.findMembersByName(name);
                for (Object memberEntry : members) {
                    print(memberEntry.toString());
                }
                long memberId = Long.parseLong(input.getString("member id"));
                memberManager.deleteMember(memberId);
            }
            print("Member deleted");
        } catch (LibraryPolicyException ex) {
            printException(ex);
            print("Outstanding loan exists! Termination of membership not allowed");
        } catch (Exception ex) {
            printException(ex);
        }
    }

    public void addTitle() {
        try {
            if (Main.isDebug) {
                collectionManager.addTitle("xiaohong", "xiaohong", "xiawei", "xiawei");
            } else {
                String name = input.getString("name");
                String isbn = input.getString("isbn");
                String author = input.getString("author");
                String publisher = input.getString("publisher");

                collectionManager.addTitle(name, isbn, author, publisher);
            }
            print("New title added");
        } catch (ExistException ex) {
            printException(ex);
        }

    }

    public void addBook() {
        long bookId = -1;
        try {
            if (Main.isDebug) {
                bookId = collectionManager.addBook("xiaohong");
            } else {
                String isbn = input.getString("isbn");

                bookId = collectionManager.addBook(isbn);
            }
            print(String.format("New book added. (ID: %d)", bookId));
        } catch (NotExistException ex) {
            printException(ex);
        }
    }

    public void deleteBook() {
        try {
            if (Main.isDebug) {
                collectionManager.deleteBook(3);
            } else {
//                String title = input.getString("title");
//                List<Object> books = collectionManager.findBooksByTitle(title);
//                for(Object bookEntry : books){
//                    print(bookEntry.toString());
//                }
                long bookId = Long.parseLong(input.getString("book id"));
                collectionManager.deleteBook(bookId);
            }
            print("Book deleted");
        } catch (NotExistException ex) {
            printException(ex);
        }
    }

    public void getLoans() {
        try {
            if (Main.isDebug) {
                List<BookState> loans = loanManager.returnLoans(1);
                for (BookState loan : loans) {
                    print(loan.toString());
                }
            }
        } catch (NotExistException ex) {
            printException(ex);
        }
    }

    public void addLoan() {
        long bookId = -1, memberId = -1;
        try {
            if (Main.isDebug) {
                loanManager.newLoan(3, 1);

            } else {
                bookId = Long.parseLong(input.getString("book id"));
                memberId = Long.parseLong(input.getString("member id"));
                loanManager.newLoan(bookId, memberId);
            }
            print("New loan added");
        } catch (LoanLimitException ex) {
            printException(ex);
        } catch (HasOutstandingLoan ex) {
            printException(ex);
        } catch (NotExistException ex) {
            printException(ex);
        }
    }

    public void endLoan() {
        long bookId = -1, memberId = -1;
        try {
            if (Main.isDebug) {
                loanManager.endLoan(3);
            } else {
                bookId = Long.parseLong(input.getString("book id"));
                loanManager.endLoan(bookId);
            }
            print("Book returned. Loan ends.");
        } catch (NotExistException ex) {
            printException(ex);
        }
    }

    private void print(String string) {
        System.out.println(String.format("%s %s", Main.isDebug ? "[DEBUG]" : "[TLS]", string));
    }

    private void printException(Exception ex) {
        print(ex.getMessage());
        if (Main.isDebug) {
            Logger.getLogger(Control.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void addReservation() {
        try {
            if (Main.isDebug) {
                loanManager.newReservation(new Long[]{203L, 204L, 351L}, 51L);
            }
        } catch (NotExistException ex) {
            Logger.getLogger(Control.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void getReservation() {
        try {
            if (Main.isDebug) {
                for (ReservationState reservation : (List<ReservationState>) loanManager.returnReservations(51)) {
                    print(reservation.toString());
                }
            }
        } catch (NotExistException ex) {
            Logger.getLogger(Control.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void findBookByAuthor() {
        if (Main.isDebug) {
            for (BookLoanState book : (List<BookLoanState>) collectionManager.findBooksByAuthor("a")) {
                print(book.toString());
            }
        }
    }

    public void findBookByTitle() {
        if (Main.isDebug) {
            for (BookLoanState book : (List<BookLoanState>) collectionManager.findBooksByTitle("b")) {
                print(book.toString());
            }
        }
    }
}
